#include "app_message.h"
#include "log/log.h"
#include "cJSON/cJSON.h"
#include <stdlib.h>
#include <string.h>

/**
 * @brief 将16进制字符串转换为整数
 */
static int hex_to_int(char hex_str)
{
    if (hex_str >= '0' && hex_str <= '9')
    {
        return hex_str - '0';
    }
    else if (hex_str >= 'A' && hex_str <= 'F')
    {
        return hex_str - 'A' + 10;
    }
    else if (hex_str >= 'a' && hex_str <= 'f')
    {
        return hex_str - 'a' + 10;
    }
}

/**
 * @brief 将16进制字符串转换为字符串
 * 61626364 -> abcd
 */
static char *hex_to_str(char *hex_str, int *str_len)
{
    // 十进制字符串长度
    int hex_len = strlen(hex_str);
    if (hex_len % 2 != 0)
    {
        log_error("hex str len error");
        return NULL;
    }

    *str_len = hex_len / 2;
    // 遍历hex_str,每两位字符对应一个字符
    char *str = (char *)malloc(*str_len);
    for (int i = 0; i < hex_len; i += 2)
    {
        int high = hex_to_int(hex_str[i]);
        int low = hex_to_int(hex_str[i + 1]);
        str[i / 2] = high * 16 + low;
    }

    // 在str后添加结束符
    str[*str_len] = '\0';

    return str;
}
/**
 * @brief 将字符串转换成16进制字符串
 */
static char *str_to_hex(char *str, int len)
{
    char *hex_str = (char *)malloc(len * 2 + 1);

    // 遍历字符串str,将每个字符转换成16进制字符串
    for (int i = 0; i < len; i++)
    {
        sprintf(hex_str + i * 2, "%02x", str[i]);
    }

    // 向hex_str最后添加结束符
    hex_str[len * 2] = '\0';
    return hex_str;
}

Message *app_message_initByBinary(char *binary, int len)
{
    Message *message = (Message *)malloc(sizeof(Message));
    memset(message, 0, sizeof(Message));

    /*
    二进制数据格式：
    1字节：消息类型
    1字节：连接类型
    4字节：消息长度
     */
    // 拷贝conn_type
    memcpy(&message->conn_type, binary, 1);
    // 拷贝id_len
    memcpy(&message->id_len, binary + 1, 1);
    // 拷贝msg_len
    memcpy(&message->msg_len, binary + 2, 1);
    // 检查len
    if (len != 3 + message->id_len + message->msg_len)
    {
        log_error("binary len error");

        free(message);
        return NULL;
    }

    message->payload = (char *)malloc(message->msg_len + message->id_len);
    // 拷贝payload
    memcpy(message->payload, binary + 3, message->msg_len + message->id_len);

    return message;
}

Message *app_message_initByJson(char *json)
{
    // 初始化message空间
    Message *message = (Message *)malloc(sizeof(Message));
    memset(message, 0, sizeof(Message));

    // 解析json得到conn_type id_hex msg_hex
    cJSON *root = cJSON_Parse(json);
    if (root == NULL)
    {
        log_error("json parse error");
        free(message);
        return NULL;
    }
    cJSON *type_obj = cJSON_GetObjectItem(root, "conn_type");
    cJSON *id_obj = cJSON_GetObjectItem(root, "id");
    cJSON *msg_obj = cJSON_GetObjectItem(root, "msg");
    if (type_obj == NULL || id_obj == NULL || msg_obj == NULL)
    {
        log_error("json 中没有 conn_type 或 id 或 msg");
        free(message);
        return NULL;
    }
    int conn_type = type_obj->valueint;
    char *id_hex = id_obj->valuestring;
    char *msg_hex = msg_obj->valuestring;

    // 将conn_type给message->conn_type
    message->conn_type = conn_type;

    // 根据id_hex msg_hexn转换成id msg
    // 将id的长度给message->id_len msg的长度给message->msg_len
    char *id = hex_to_str(id_hex, &message->id_len);
    char *msg = hex_to_str(msg_hex, &message->msg_len);

    message->payload = (char *)malloc(message->msg_len + message->id_len);
    // 将id msg给message->payload
    memcpy(message->payload, id, message->id_len);
    memcpy(message->payload + message->id_len, msg, message->msg_len);

    // 释放json对象
    cJSON_Delete(root);
    free(id);
    free(msg);
    return message;
}

int app_message_toBinary(Message *message, char *binary, int len)
{
    // 检查len
    if (len < 3 + message->id_len + message->msg_len)
    {
        log_error("binary len error");

        return -1;
    }
    // 拷贝conn_type
    memcpy(binary, &message->conn_type, 1);
    // 拷贝id_len
    memcpy(binary + 1, &message->id_len, 1);
    // 拷贝msg_len
    memcpy(binary + 2, &message->msg_len, 1);
    // 拷贝payload
    memcpy(binary + 3, message->payload, message->msg_len + message->id_len);

    return 3 + message->id_len + message->msg_len;
}

int app_message_toJson(Message *message, char *json, int len)
{
    // 创建空cjson对象
    cJSON *root = cJSON_CreateObject();

    // 将message->conn_type给cjson对象
    cJSON_AddNumberToObject(root, "conn_type", message->conn_type);

    // // 从message->payload 取出id和msg
    // char *id = malloc(message->id_len + 1);
    // char *msg = malloc(message->msg_len + 1);
    // memcpy(id, message->payload, message->id_len);
    // memcpy(msg, message->payload + message->id_len, message->msg_len);

    // 将message中的payload 的id和msg给转换成16进制字符串，添加到cjson对象中
    char *id_hex = str_to_hex(message->payload, message->id_len);
    char *msg_hex = str_to_hex(message->payload + message->id_len, message->msg_len);
    cJSON_AddStringToObject(root, "id", id_hex);
    cJSON_AddStringToObject(root, "msg", msg_hex);
    // 将cjson对象转换成json字符串
    char *json_str = cJSON_PrintUnformatted(root);
    if (len < sizeof(json_str) + 1)
    {
        log_error("json len error");
        free(json_str);
        return -1;
    }

    // 将json字符串拷贝到json参数中
    strcpy(json, json_str);

    // 释放cjson对象
    cJSON_Delete(root);
    free(json_str);
    free(id_hex);
    free(msg_hex);

    // 返回json字符串的长度
    return strlen(json);
}

void app_message_free(Message *message)
{
    if (message->payload)
    {
        free(message->payload);
    }

    free(message);
}
